package com.wywah.yunduo.security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wywah.yunduo.orm.bean.Client;
import com.wywah.yunduo.orm.dao.ClientMapper;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.Arrays;
import java.util.Objects;

@Service
public class YunduoRegisteredClientRepository implements RegisteredClientRepository {

    private final ClientMapper clientMapper;

    public YunduoRegisteredClientRepository(ClientMapper clientMapper) {
        this.clientMapper = clientMapper;
    }

    @Override
    public void save(RegisteredClient registeredClient) {

    }

    @Override
    public RegisteredClient findById(String id) {
        return null;
    }

    @Override
    public RegisteredClient findByClientId(String clientId) {
        LambdaQueryWrapper<Client> query = new LambdaQueryWrapper<>();
        query.eq(Client::getClientId, clientId);
        Client client = clientMapper.selectOne(query);
        if(Objects.nonNull(client)) {
            /**
             * token相关设置
             */
            TokenSettings tokenSettings = TokenSettings.builder()
                    .accessTokenFormat(OAuth2TokenFormat.REFERENCE)
                    .accessTokenTimeToLive(Duration.ofSeconds(client.getAccessTokenValidity()))
                    .refreshTokenTimeToLive(Duration.ofSeconds(client.getRefreshTokenValidity()))
                    .build();
            /**
             * 客户端相关设置
             */
            ClientSettings clientSettings = ClientSettings.builder().requireAuthorizationConsent(false).build();
            return RegisteredClient.withId(client.getClientId())
                    .clientId(client.getClientId())
                    .clientSecret(String.format("{%s}%s", client.getEncrypt(), client.getClientSecret()))
                    .clientAuthenticationMethods((methods) -> {
                        String methods1 = client.getMethods();
                        if(StringUtils.hasText(methods1)){
                            for (String method : methods1.split(",")) {
                                methods.add(new ClientAuthenticationMethod(method));
                            }
                        }
                    }).authorizationGrantTypes((grantTypes) -> {
                        String grantType = client.getGrantType();
                        if(StringUtils.hasText(grantType)){
                            for (String grant : grantType.split(",")) {
                                grantTypes.add(new AuthorizationGrantType(grant));
                            }
                        }
                    }).redirectUris((redirectUris) -> {
                        String redirectUri = client.getRedirectUri();
                        if(StringUtils.hasText(redirectUri)){
                            redirectUris.add(redirectUri);
                        }
                    }).scopes(scopes -> {
                        String scope = client.getScope();
                        if(StringUtils.hasText(scope)){
                            scopes.addAll(Arrays.asList(scope.split(",")));
                        }
                    })
                    .tokenSettings(tokenSettings)
                    .clientSettings(clientSettings)
                    .build();
        }
        return null;
    }
}
